﻿using System.Collections.Generic;
using UnityEngine;

public class GraphUnityObject : UnityObject
{
    public enum SearchAlgorithm
    {
        DFS,
        BFS,
        Dijkstra,
        AStar,
    }

    public SearchAlgorithm algorithm = SearchAlgorithm.AStar;

    private void OnDrawGizmos()
    {
        Graph graph = _linkedEntity.graph.graph;
        Gizmos.color = Color.white;
        List<GraphNode> nodes = graph.GetNodes();
        foreach (var node in nodes)
        {
            List<GraphEdge> edges = graph.GetEdges(node.index);
            foreach (var edge in edges)
            {
                GraphNode fromNode = graph.GetNode(edge.from);
                GraphNode toNode = graph.GetNode(edge.to);
                DrawLine(fromNode.position, toNode.position);
            }
        }

        GraphSearch search = new GraphSearch(graph);

        bool found = false;
        int source = 280;
        int target = 180;
        if (algorithm == SearchAlgorithm.Dijkstra)
        {
            found = search.SearchDijkstra(source, target);
        }
        else if (algorithm == SearchAlgorithm.DFS)
        {
            found = search.SearchDFS(source, target);
        }
        else if (algorithm == SearchAlgorithm.BFS)
        {
            found = search.SearchBFS(source, target);
        }
        else if (algorithm == SearchAlgorithm.AStar)
        {
            found = search.SearchAStar(source, target);
        }

        if (found)
        {
            Gizmos.color = Color.red;
            List<GraphEdge> spanningTree = search.GetSpanningTree();
            foreach (var edge in spanningTree)
            {
                if (edge == null)
                {
                    continue;
                }

                GraphNode fromNode = graph.GetNode(edge.from);
                GraphNode toNode = graph.GetNode(edge.to);
                DrawLine(fromNode.position, toNode.position);
            }

            Gizmos.color = Color.blue;
            List<int> path = search.GetPathToTarget();
            for (int i = 1; i < path.Count; i++)
            {
                GraphNode fromNode = graph.GetNode(path[i - 1]);
                GraphNode toNode = graph.GetNode(path[i]);
                DrawLine(fromNode.position, toNode.position);
            }
        }
    }

    private void DrawLine(Vector3 from, Vector3 to)
    {
        Vector3 offset = new Vector3(0, 0.05f, 0);
        Gizmos.DrawLine(from + offset, to + offset);
    }
}